﻿namespace Sai.Core.Introspection
{
	using System;
	using System.Text;

	public class PropertyDeclaration : FunctionMember, IExactlyMatch<PropertyDeclaration>, ILooselyMatch<PropertyDeclaration>, ISourceCodeProvider 
	{
		public PropertyDeclaration(TypeName typeName)
			: base(typeName)
		{
		}

		public PropertyDeclaration(string name, TypeName typeName, ObsoleteMarker obsolete, TypeName declaringType)
			: base(typeName, obsolete, declaringType)
		{
			this.Name = name;
		}

		public string Name { get; set; }

		public bool HasPublicGetter { get; set; }

		public bool HasPublicSetter { get; set; }

		// distinction between to string and fully qualified name 
		public override string ToString()
		{
            return string.Empty; // this.ToCode();
		}

		public bool ExactMatchFor(PropertyDeclaration other)
		{
            // exact match is not needed for property - 
            // match on name and then dig deeper on setters/getters etc.

            return this.LooseMatchFor(other);
            //// and has same return type, etc.
            //return string.Compare(
            //    this.Name,
            //    other.Name,
            //    StringComparison.Ordinal) == 0;

            //if (exact)
            //{
            //    exact = this.TypeName.Equals(other.TypeName);
            //}

            //if (exact)
            //{
            //    exact = (this.HasPublicGetter == other.HasPublicGetter)
            //        && (this.HasPublicSetter == other.HasPublicSetter);
            //}

            //return exact;
		}

		public SourceCode ToCode()
		{
            SourceCode code = new SourceCode();

            code.Add(this.TypeName.ToCode());
            code.Add(new IdentifierTag(this.Name));

            if (this.HasPublicGetter || this.HasPublicSetter)
            {
                code.Add(new PunctuationTag("{"));

                if (this.HasPublicGetter)
                {
                    code.Add(new KeywordTag("get;"));
                }

                if (this.HasPublicSetter)
                {
                    code.Add(new KeywordTag("set;"));
                }

                code.Add(new PunctuationTag("}"));
            }

            return code;
		}

		// we only care if the property name matches...
		public bool LooseMatchFor(PropertyDeclaration other)
		{
			return string.Compare(
				this.Name,
				other.Name,
				StringComparison.Ordinal) == 0;
		}
	}
}
